package com.youlai.mall.ums.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.conditions.update.LambdaUpdateChainWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.youlai.common.result.ResultCode;
import com.youlai.common.security.util.SecurityUtils;
import com.youlai.common.web.exception.BizException;
import com.youlai.mall.pms.model.vo.ProductHistoryVO;
import com.youlai.common.constant.MemberConstants;
import com.youlai.mall.ums.convert.AddressConvert;
import com.youlai.mall.ums.convert.MemberConvert;
import com.youlai.mall.ums.dto.MemberAddressDTO;
import com.youlai.mall.ums.dto.MemberAuthDTO;
import com.youlai.mall.ums.dto.MemberInfoDTO;
import com.youlai.mall.ums.dto.MemberRegisterDto;
import com.youlai.mall.ums.mapper.UmsMemberMapper;
import com.youlai.mall.ums.model.entity.UmsAddress;
import com.youlai.mall.ums.model.entity.UmsMember;
import com.youlai.mall.ums.model.form.WeChatInfo;
import com.youlai.mall.ums.model.vo.MemberVO;
import com.youlai.mall.ums.service.UmsAddressService;
import com.youlai.mall.ums.service.UmsMemberService;
import io.swagger.v3.core.util.Json;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Objects;
import java.util.Set;

/**
 * 会员业务实现类
 *
 * @author haoxr
 * @since 2022/2/12
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class UmsMemberServiceImpl extends ServiceImpl<UmsMemberMapper, UmsMember> implements UmsMemberService {

    private final RedisTemplate redisTemplate;
    private final MemberConvert memberConvert;

    private final AddressConvert addressConvert;
    private final UmsAddressService addressService;

    @Override
    public IPage<UmsMember> list(Page<UmsMember> page, String nickname) {
        List<UmsMember> list = this.baseMapper.list(page, nickname);
        page.setRecords(list);
        return page;
    }

    @Override
    public void addProductViewHistory(ProductHistoryVO product, Long userId) {
        if (userId != null) {
            String key = MemberConstants.USER_PRODUCT_HISTORY + userId;
            redisTemplate.opsForZSet().add(key, product, System.currentTimeMillis());
            Long size = redisTemplate.opsForZSet().size(key);
            if (size > 10) {
                redisTemplate.opsForZSet().removeRange(key, 0, size - 11);
            }
        }
    }

    @Override
    public Set<ProductHistoryVO> getProductViewHistory(Long userId) {
        return redisTemplate.opsForZSet().reverseRange(MemberConstants.USER_PRODUCT_HISTORY + userId, 0, 9);
    }

    /**
     * 根据 openid 获取会员认证信息
     *
     * @param openid 微信唯一身份标识
     * @return
     */
    @Override
    public MemberAuthDTO getMemberByOpenid(String openid) {
        UmsMember entity = this.getOne(new LambdaQueryWrapper<UmsMember>()
                .eq(UmsMember::getOpenid, openid)
                .select(UmsMember::getId,
                        UmsMember::getOpenid,
                        UmsMember::getStatus
                )
        );

        if (entity == null) {
            // 用户不存在，创建新用户
            UmsMember newMember = new UmsMember();
            newMember.setOpenid(openid);
            newMember.setStatus(1); // 假设 1 表示正常状态
            boolean result = this.save(newMember);
            if(!result) {
                throw new BizException(ResultCode.USER_NOT_EXIST);
            }
            entity = newMember;
        }
        log.info("Creating new user with openid: {}", openid);
        return memberConvert.entity2OpenidAuthDTO(entity);
    }

    /**
     * 根据手机号获取会员认证信息
     *
     * @param mobile
     * @return
     */
    @Override
    public MemberAuthDTO getMemberByMobile(String mobile) {
        System.out.println(mobile);
        UmsMember entity = this.getOne(new LambdaQueryWrapper<UmsMember>()
                .eq(UmsMember::getMobile, mobile)
                .select(UmsMember::getId,
                        UmsMember::getMobile,
                        UmsMember::getStatus
                )
        );
        int firstLogin = 0;
        if (entity == null) {
            firstLogin = 1;
            // 创建新用户时生成昵称
            UmsMember newMember = new UmsMember();
            newMember.setMobile(mobile);
            newMember.setStatus(1);
            newMember.setNickName(generateNickname(mobile)); // 调用昵称生成方法
            //这里没有openid，想办法搞到openid
            boolean result = this.save(newMember);
            if (!result) {
                throw new BizException(ResultCode.USER_NOT_EXIST);
            }
            entity = newMember;
        }
        MemberAuthDTO memberAuthDTO = memberConvert.entity2MobileAuthDTO(entity);
        memberAuthDTO.setFirstLogin(firstLogin);
        return memberAuthDTO;
    }

    private String generateNickname(String mobile) {
        // 示例1：取后4位 + 前缀
//        String suffix = mobile.substring(mobile.length() - 4);
//        return "用户" + suffix; // 如：用户5678

        // 示例2：直接使用完整手机号（不推荐）
        return mobile;

        // 示例3：中间四位星号
        // return mobile.replaceAll("(\\d{3})\\d{4}(\\d{4})", "$1****$2");
    }

    /**
     * 新增会员
     *
     * @param memberRegisterDTO
     * @return
     */
    @Override
    public Long addMember(MemberRegisterDto memberRegisterDTO) {
        UmsMember umsMember = memberConvert.dto2Entity(memberRegisterDTO);
        boolean result = this.save(umsMember);
        Assert.isTrue(result, "新增会员失败");
        return umsMember.getId();
    }

    /**
     * 获取登录会员信息
     *
     * @return
     */
    @Override
    public MemberVO getCurrMemberInfo(String code) {
        Long memberId = SecurityUtils.getMemberId();
        UmsMember umsMember = this.getOne(new LambdaQueryWrapper<UmsMember>()
                .eq(UmsMember::getId, memberId)
                .select(UmsMember::getId,
                        UmsMember::getNickName,
                        UmsMember::getAvatarUrl,
                        UmsMember::getMobile,
                        UmsMember::getBalance,
                        UmsMember::getCoupon,
                        UmsMember::getOpenid
                )
        );
        if(StringUtils.isBlank(umsMember.getOpenid()) && StringUtils.isNotBlank(code)){
            //说明这个人是第一次登录之后来获取用户信息,那么code就不应该为空
            //根据code获取到openid 给这个用户设置上去
            String openid = this.getOpenidByCode(code);
            if (StringUtils.isNotBlank(openid)) {
                this.update(new LambdaUpdateWrapper<UmsMember>()
                        .eq(UmsMember::getId, memberId)  // 根据ID匹配（NickName字段可能不准确）
                        .set(UmsMember::getOpenid, openid)
                );
            }
        }
        MemberVO memberVO = new MemberVO();
        BeanUtil.copyProperties(umsMember, memberVO);
        return memberVO;
    }

    /**
     * 获取会员地址
     *
     * @param memberId
     * @return
     */
    @Override
    public List<MemberAddressDTO> listMemberAddress(Long memberId) {

        List<UmsAddress> entities = addressService.list(
                new LambdaQueryWrapper<UmsAddress>()
                        .eq(UmsAddress::getMemberId, memberId)
        );

        List<MemberAddressDTO> list = addressConvert.entity2Dto(entities);
        return list;
    }


    /**
     * 同步微信用户信息
     * @param weChatInfo
     * @return
     */
    @Override
    public boolean syncCurrmember(WeChatInfo weChatInfo) {
        Long memberId = SecurityUtils.getMemberId();
        UmsMember umsMember = this.getOne(new LambdaQueryWrapper<UmsMember>()
                .eq(UmsMember::getId, memberId)
                .select(UmsMember::getId,
                        UmsMember::getNickName,
                        UmsMember::getAvatarUrl,
                        UmsMember::getMobile,
                        UmsMember::getBalance,
                        UmsMember::getCoupon
                )
        );
        if(umsMember == null){
            return false;
        }
        int i = 0;
        LambdaUpdateWrapper<UmsMember> umsMemberLambdaUpdateWrapper = new LambdaUpdateWrapper<>();
        if(!Objects.equals(weChatInfo.getAvatarUrl(),umsMember.getAvatarUrl())){
            i++;
            umsMemberLambdaUpdateWrapper.set(UmsMember::getAvatarUrl,weChatInfo.getAvatarUrl());


        }
        if(!Objects.equals(weChatInfo.getGender(),umsMember.getGender())){
            i++;
            umsMemberLambdaUpdateWrapper.set(UmsMember::getGender, weChatInfo.getGender());
        }
        if (!Objects.equals(weChatInfo.getNickName(),umsMember.getNickName())){
            i++;
            umsMemberLambdaUpdateWrapper.set(UmsMember::getNickName,weChatInfo.getNickName());
        }
        if(i > 0){
            umsMemberLambdaUpdateWrapper.eq(UmsMember::getId, memberId);
            return this.update(umsMemberLambdaUpdateWrapper);
        }
        return true;
    }

    /**
     * 根据会员唯一标识获取会员信息
     * @param memberId
     * @return
     */
    @Override
    public MemberInfoDTO getMemberInfo(String memberId) {
        UmsMember umsMember = this.getById(memberId);
        return memberConvert.entity2MemberInfoDTO(umsMember);

    }

    public String getOpenidByCode(String code) {
        String appId = "*********************";
        String appSecret = "**************************";

        String url = "https://api.weixin.qq.com/sns/jscode2session";
        String params = String.format(
                "appid=%s&secret=%s&js_code=%s&grant_type=authorization_code",
                appId,appSecret,code
        );
        try {
            String response = HttpUtil.get(url + "?" + params);
            JSONObject json = JSON.parseObject(response);

            if (json.containsKey("errorcode")) {
                log.error("接口错误{}",json.getString("errmsg"));
                return null;
            }
            return json.getString("openid");
        } catch (Exception e) {
            log.error("获取openid失败:{}",e.getMessage());
            return null;
        }
    }
}
